package com.smartwebx.ha.dal.util.aspect;

import java.util.Map;
import java.util.Set;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.smartwebx.ha.dal.config.StatGroupThreadLocal;
import com.smartwebx.ha.dal.usebean.abstr.AbstractStation;

/**
 * 在 realtime、feature 调用特定方法之后对返回数据进行条件过滤
 * 
 * @author zhangxi
 * 
 */
//@Component
//@Aspect
//@Order(value = 2)
public class StcdGroupsFilterAfter {
	@Around("execution(* com..dal.realtime.dao.*.*StcdFilter*(..)) "
			+ " || execution(* com..dal.feature.dao.*.*StcdFilter*(..))")
	public Object doAroundAfter(ProceedingJoinPoint jp) throws Throwable {
		Object result = jp.proceed();
		final Set<String> statGroups = StatGroupThreadLocal.getStatGroups();
		if (!StatGroupThreadLocal.getInWeb()) {// 没有在web容器中运行
			return result;
		} else if (statGroups == null) {
			throw new Exception("用户站群获取失败");
		}
		if (result instanceof Iterable<?>) {
			Iterable<?> resultIter = (Iterable<?>) result;
			Predicate<Object> predicate = new Predicate<Object>() {
				@Override
				public boolean apply(Object input) {
					if (input == null)
						return false;
					String stcd = null;
					if (input instanceof AbstractStation) {
						AbstractStation inputStation = (AbstractStation) input;
						stcd = inputStation.getStcd();
					} else if (input instanceof String) {
						stcd = (String) input;
					}
					return stcd != null ? statGroups.contains(stcd) : false;
				}
			};
			Iterable<?> filterResult = Iterables.filter(resultIter, predicate);
			result = Lists.newArrayList(filterResult);
		} else if (result instanceof Map<?, ?>) {
			@SuppressWarnings("unchecked")
			Map<String, ?> resultMap = (Map<String, ?>) result;
			Map<String, ?> filterResult = Maps.filterKeys(resultMap,
					new Predicate<String>() {
						@Override
						public boolean apply(String input) {
							return input != null ? statGroups.contains(input)
									: false;
						}
					});
			result = filterResult;
		}

		return result;
	}
}
